/**
 * ============服务器启动文件开始===========
 * 这个文件的职责：
 * 1. 启动 HTTP 服务器
 * 2. 处理服务器生命周期事件
 * 3. 设置优雅关闭机制
 * 4. 处理未捕获的异常和 Promise 拒绝
 * 
 * 为什么要单独一个启动文件？
 * - 分离关注点：app.js 负责应用配置，server.js 负责服务器启动
 * - 便于测试：可以在测试中导入 app.js 而不启动服务器
 * - 便于部署：不同环境可能需要不同的启动配置
 */

// 导入应用实例和日志工具
import app from "./app.js";                    // 导入配置好的 Express 应用
                                               // 为什么从 app.js 导入？因为所有的中间件和路由配置都在那里
import { logger } from "./utils/logger.js";    // 导入日志记录工具
                                               // 为什么使用自定义 logger？统一日志格式，便于日志收集和分析

/**
 * 第一步：设置服务器端口
 * 
 * 为什么使用环境变量？
 * - 开发环境、测试环境、生产环境可能需要不同的端口
 * - 云平台（如 Heroku、AWS）会动态分配端口
 * - 避免端口冲突，提高部署灵活性
 * 
 * 为什么默认端口是 3000？
 * - Node.js 应用的常见默认端口
 * - 不与系统保留端口冲突（0-1023）
 * - 便于开发时记忆和使用
 */
const PORT = process.env.PORT || 3000;

/**
 * 第二步：启动 HTTP 服务器
 * 
 * app.listen() 做了什么？
 * - 创建 HTTP 服务器实例
 * - 绑定到指定端口
 * - 开始监听传入的连接
 * - 执行回调函数（服务器启动成功后）
 */
const server = app.listen(PORT, () => {
  // 服务器启动成功后的回调函数
  // 为什么要记录这些信息？便于开发者确认服务器状态和访问地址
  logger.info(`🚀 服务器已启动，端口 ${PORT}`);
  logger.info(`📡 API 地址: http://localhost:${PORT}/api`);
  logger.info(`🏥 健康检查: http://localhost:${PORT}/api/health`);
  logger.info(`🌍 环境: ${process.env.NODE_ENV || 'development'}`);
  logger.info(`📝 日志级别: ${process.env.LOG_LEVEL || 'info'}`);
});

/**
 * 第三步：优雅关闭处理
 * 
 * 什么是优雅关闭？
 * - 收到终止信号时，不立即杀死进程
 * - 先停止接受新请求
 * - 等待现有请求处理完成
 * - 关闭数据库连接等资源
 * - 最后退出进程
 * 
 * 为什么需要优雅关闭？
 * - 避免数据丢失或损坏
 * - 确保用户请求得到正确响应
 * - 释放系统资源，避免内存泄漏
 */

// SIGTERM - 终止信号（通常由进程管理器发送）
process.on('SIGTERM', () => {
  logger.info('🛑 收到 SIGTERM 信号，正在优雅关闭服务器...');
  
  // 关闭 HTTP 服务器，停止接受新连接
  server.close((err) => {
    if (err) {
      logger.error('关闭服务器时出错:', err);
      process.exit(1);
    }
    
    logger.info('✅ 服务器已优雅关闭');
    process.exit(0);
  });
  
  // 设置超时，如果 30 秒内无法优雅关闭，强制退出
  setTimeout(() => {
    logger.error('⏰ 优雅关闭超时，强制退出');
    process.exit(1);
  }, 30000);
});

// SIGINT - 中断信号（通常由 Ctrl+C 触发）
process.on('SIGINT', () => {
  logger.info('🛑 收到 SIGINT 信号（Ctrl+C），正在优雅关闭服务器...');
  
  server.close((err) => {
    if (err) {
      logger.error('关闭服务器时出错:', err);
      process.exit(1);
    }
    
    logger.info('✅ 服务器已优雅关闭');
    process.exit(0);
  });
  
  setTimeout(() => {
    logger.error('⏰ 优雅关闭超时，强制退出');
    process.exit(1);
  }, 30000);
});

/**
 * 第四步：未捕获异常处理
 * 
 * 为什么需要处理未捕获异常？
 * - 防止应用因未处理的错误而崩溃
 * - 记录错误信息，便于问题排查
 * - 在生产环境中保持服务稳定性
 */

// 捕获未处理的 Promise 拒绝
// 什么时候会发生？当 async/await 或 Promise 没有正确处理错误时
process.on('unhandledRejection', (reason, promise) => {
  logger.error('❌ 未处理的 Promise 拒绝:', reason);
  logger.error('Promise:', promise);
  
  // 在生产环境中，可能需要优雅关闭服务器
  if (process.env.NODE_ENV === 'production') {
    logger.error('🚨 生产环境检测到未处理的 Promise 拒绝，准备关闭服务器');
    server.close(() => {
      process.exit(1);
    });
  }
});

// 捕获未捕获的异常
// 什么时候会发生？当同步代码抛出异常但没有被 try-catch 捕获时
process.on('uncaughtException', (error) => {
  logger.error('💥 未捕获的异常:', error);
  logger.error('堆栈跟踪:', error.stack);
  
  // 未捕获的异常通常意味着应用处于不稳定状态，应该退出
  logger.error('🚨 应用处于不稳定状态，正在退出...');
  process.exit(1);
});

/**
 * 导出服务器实例（可选）
 * 
 * 为什么要导出？
 * - 便于测试时关闭服务器
 * - 便于其他模块获取服务器状态
 * - 支持更复杂的服务器管理需求
 */
export { server };

// ============服务器启动文件结束===========
